package com.fat;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.sql.Types;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * 代码生成器
 */
public class CodeGenerator {
    public static void main(String[] args) {

        String database = "springboot3_template";
        String dataTable = "goods";
        // 项目所在的绝对路径,配置错了会导致生成的文件不在目标文件夹下
        String projectPath = "F:\\1.ProjectManagement\\template\\SpringBoot3+Vue3 Template\\spring-boot3---vue3-template\\springboot3_template-master";

        // 数据库连接信息
        String username = "root";
        String password = "root";
        String url = "jdbc:mysql://localhost:3306/"+database+"?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC";
        // 生成代码
        FastAutoGenerator.create(url, username, password)
                .globalConfig(builder -> {
                    builder.author("fat")
                            .enableSwagger()
                            .outputDir(projectPath + "\\src\\main\\java")
                            .commentDate("yyyy-MM-dd")
                            .build();
                })
                .dataSourceConfig(builder -> {
                    builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
                        int typeCode = metaInfo.getJdbcType().TYPE_CODE;
                        if (typeCode == Types.SMALLINT) {
                            return DbColumnType.INTEGER;
                        }
                        return typeRegistry.getColumnType(metaInfo);
                    });
                })
                .packageConfig(builder -> {
                    builder.parent("com.fat") // 父包名
                            .entity("entity") // 实体类包名
                            .mapper("mapper") // mapper包名
                            .service("service") // service包名
                            .serviceImpl("service.impl") // service实现类包名
                            .controller("controller") // controller包名
                            .xml("mapper") // mapper.xml包名
                            .pathInfo(getPathInfo(projectPath)) // 设置输出路径
                            .build();
                })
                .strategyConfig(builder -> {
                    builder.addInclude(dataTable) // 需要生成的表名,多个表名使用逗号分隔,例：addInclude("car","student")
                            .addTablePrefix("t_", "c_") // 去掉表前缀
                            .entityBuilder() // 实体类配置
                            .enableLombok() // 开启lombok
                            .enableTableFieldAnnotation() // 开启字段注解
                            .controllerBuilder() // controller配置
                            .enableRestStyle() // 开启rest风格
                            .build();
                })
                .templateConfig(builder -> {
                    builder.controller("/templates/controller.java.ftl") // 自定义controller模板
                            .entity("/templates/entity.java.ftl") // 自定义entity模板
                            .build();
                })
                .injectionConfig(builder -> {
                    Map<String, String> customFile = new HashMap<>();
                    // 使用简短后缀，避免拼接多余部分
                    customFile.put(".js", "/templates/page.js.ftl"); // 生成 xxx.js
                    customFile.put(".vue", "/templates/page.vue.ftl"); // 生成 xxx.vue,默认text类型使用富文本编辑器处理,或者字段备注包含"富文本"字样,image字段使用文件上传处理,或者字段备注包含"文件上传"字样

                    builder.beforeOutputFile((tableInfo, objectMap) -> {
                                // 自定义文件名
                                Map<String, String> newFileMap = new HashMap<>();
                                String entityLowerCase = tableInfo.getEntityName().toLowerCase();
                                newFileMap.put(entityLowerCase + ".js", tableInfo.getEntityPath() + ".js"); // xxx.js
                                newFileMap.put("index.vue", "index.vue"); // index.vue
                                objectMap.put("customFile", newFileMap); // 覆盖默认文件名
                            })
                            .customFile(customFile)
                            .build();
                })
                .templateEngine(new FreemarkerTemplateEngine())
                .execute();
    }

    /**
     * 设置输出路径
     */
    private static Map<OutputFile, String> getPathInfo(String projectPath) {
        Map<OutputFile, String> pathInfo = new HashMap<>();
        pathInfo.put(OutputFile.entity, projectPath + "\\src\\main\\java\\com\\fat\\entity");
        pathInfo.put(OutputFile.controller, projectPath + "\\src\\main\\java\\com\\fat\\controller");
        pathInfo.put(OutputFile.service, projectPath + "\\src\\main\\java\\com\\fat\\service");
        pathInfo.put(OutputFile.serviceImpl, projectPath + "\\src\\main\\java\\com\\fat\\service\\impl");
        pathInfo.put(OutputFile.mapper, projectPath + "\\src\\main\\java\\com\\fat\\mapper");
        pathInfo.put(OutputFile.xml, projectPath + "\\src\\main\\resources\\mapper");
        // 前端文件生成路径
        pathInfo.put(OutputFile.parent, projectPath + "\\src\\main\\resources\\vue");
        return pathInfo;
    }
}

